﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using NK.Mvc3.Lib;
using NK.Mvc3.Models;
using NK.Mvc3.DBL;
using NK.Mvc3.ViewModels;
using Excel = Microsoft.Office.Interop.Excel;
using PagedList;

namespace NK.Mvc3.Controllers
{ 
    public class ProductInfoController : Controller
    {
        private StoreContext db = new StoreContext();

        //
        // GET: /ProductInfo/

        public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
        {
            ViewBag.CurrentSort = sortOrder;
            ViewBag.GroupSortParm = String.IsNullOrEmpty(sortOrder) ? "Group desc" : "";
            ViewBag.BarCodeSortParm = sortOrder == "BarCode" ? "BarCode desc" : "BarCode";
            ViewBag.POSDescriptionSortParm = sortOrder == "POSDescription" ? "POSDescription desc" : "POSDescription";
            ViewBag.ProductNameSortParm = sortOrder == "ProductName" ? "ProductName desc" : "ProductName";
            ViewBag.CostSortParm = sortOrder == "Cost" ? "Cost desc" : "Cost";
            //ViewBag.StockSortParm = sortOrder == "Stock" ? "Stock desc" : "Stock";
            
            if (Request.HttpMethod == "GET")
            {
                searchString = currentFilter;
            }
            else
            {
                page = 1;
            }
            ViewBag.CurrentFilter = searchString;

            var productInfos = from p in db.ProductInfos
                               select p;

            if (!String.IsNullOrEmpty(searchString))
            {
                productInfos = productInfos.Where(p => p.BarCode.Contains(searchString)
                                       || p.POSDescription.ToUpper().Contains(searchString.ToUpper())
                                       || p.ProductName.ToUpper().Contains(searchString.ToUpper())
                                       || p.Group.ToUpper().Contains(searchString.ToUpper()));
            }

            switch (sortOrder)
            {
                case "Group desc":
                    productInfos = productInfos.OrderByDescending(p => p.Group);
                    break;
                case "BarCode desc":
                    productInfos = productInfos.OrderByDescending(p => p.BarCode);
                    break;
                case "BarCode":
                    productInfos = productInfos.OrderBy(p => p.BarCode);
                    break;
                case "POSDescription desc":
                    productInfos = productInfos.OrderByDescending(p => p.POSDescription);
                    break;
                case "POSDescription":
                    productInfos = productInfos.OrderBy(p => p.POSDescription);
                    break;
                case "Cost desc":
                    productInfos = productInfos.OrderByDescending(p => p.Cost);
                    break;
                case "Cost":
                    productInfos = productInfos.OrderBy(p => p.Cost);
                    break;
                //case "Stock desc":
                //    productInfos = productInfos.OrderByDescending(p => p.TotalStock);
                //    break;
                //case "Stock":
                //    productInfos = productInfos.OrderBy(p => p.TotalStock);
                //    break;
                case "ProductName desc":
                    productInfos = productInfos.OrderByDescending(p => p.ProductName);
                    break;
                case "ProductName":
                    productInfos = productInfos.OrderBy(p => p.ProductName);
                    break;
                default:
                    productInfos = productInfos.OrderBy(p => p.Group);
                    break;
            }

            int pageSize = 20;
            int pageNumber = (page ?? 1);
            ViewBag.ProductNumber = productInfos.Count();

            return View(productInfos.ToPagedList(pageNumber, pageSize));
        }

        //
        // GET: /ProductInfo/Details/5

        public ViewResult Details(int id)
        {
            ProductInfo productinfo = db.ProductInfos.Find(id);
            return View(productinfo);
        }

        //
        //GET: /ProductInfo/GetDetails?barcode=9843112455
        //[HttpPost]
        public ActionResult GetDetails(string barcode)
        {
            //Thread.Sleep(2000);
            var productInfo = db.ProductInfos.Where(p => p.BarCode == barcode).SingleOrDefault();
            if (productInfo != null)
            {
                var json = Json(productInfo.ToDictionary());
                return json;
            }
            return null;
            //return "sometextfrom getDetails(barcode)";
        }

        //
        // GET: /ProductInfo/Create

        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /ProductInfo/Create

        [HttpPost]
        public ActionResult Create(ProductInfo productinfo)
        {
            if (ModelState.IsValid)
            {
                db.ProductInfos.Add(productinfo);
                db.SaveChanges();
                return RedirectToAction("Index");  
            }

            return View(productinfo);
        }
        
        //
        // GET: /ProductInfo/Edit/5
 
        public ActionResult Edit(int id)
        {
            ProductInfo productinfo = db.ProductInfos.Find(id);
            return View(productinfo);
        }

        //
        // POST: /ProductInfo/Edit/5

        [HttpPost]
        public ActionResult Edit(ProductInfo productinfo)
        {
            if (ModelState.IsValid)
            {
                db.Entry(productinfo).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(productinfo);
        }

        //
        // GET: /ProductInfo/Delete/5
 
        public ActionResult Delete(int id)
        {
            ProductInfo productinfo = db.ProductInfos.Find(id);
            return View(productinfo);
        }

        //
        // POST: /ProductInfo/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {            
            ProductInfo productinfo = db.ProductInfos.Find(id);
            db.ProductInfos.Remove(productinfo);
            db.SaveChanges();
            return RedirectToAction("Index");
        }


        public ActionResult Import()
        {
            return View(new ProductInfoExcelImport());
        }

        [HttpPost]
        public ActionResult Import(ProductInfoExcelImport importInfo)
        {
            foreach (string item in Request.Files)
            {
                HttpPostedFileBase file = Request.Files[item] as HttpPostedFileBase;
                if (file.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(file.FileName);
                    var path = Path.Combine(Server.MapPath("~/uploads"), fileName);
                    file.SaveAs(path);

                    //ProductMasterImportVM model = new ProductMasterImportVM();
                    //model.FileName = fileName;

                    ProcessExcelData(path, importInfo);

                    //ViewBag.FileName = fileName;
                    //model.IsSuccess = true;

                    break;
                }
            }
            return View("Import", new ProductInfoExcelImport());
        }

        private void ProcessExcelData(string path, ProductInfoExcelImport importInfo)
        {
            //ProductMasterTemplate template = db.ProductMasterTemplates.Find(model.ProductMasterTemplateID);

            //var result = new List<List<string>>();

            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;
            Excel.Range range;

            //File excelFile = file.

            xlApp = new Excel.Application();
            xlWorkBook = xlApp.Workbooks.Open(path, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(string.IsNullOrEmpty(importInfo.SheetName)? "MASTER LIST":importInfo.SheetName);
            //(Excel.Worksheet) xlWorkBook.Worksheets.get_Item("PO-GRN D1");

            range = xlWorkSheet.UsedRange;
            int toLine = (importInfo.ToLine == 0 ? range.Rows.Count : importInfo.ToLine);
            int fromLine = (importInfo.FromLine == 0 ? 3 : importInfo.FromLine);
            var dbProductInfos = db.ProductInfos.ToList();
            for (int rCnt = fromLine; rCnt <= toLine; rCnt++)
            {
                var productInfo = new ProductInfo();
                productInfo.Group = (string)(range.Cells[rCnt, 2] as Excel.Range).Value2;
                productInfo.BarCode = (string)(range.Cells[rCnt, 3] as Excel.Range).Value2;
                productInfo.SpecialBarCode = (string)(range.Cells[rCnt, 4] as Excel.Range).Value2;
                productInfo.ProductName = (string)(range.Cells[rCnt, 5] as Excel.Range).Value2;
                productInfo.POSDescription = (string)(range.Cells[rCnt, 6] as Excel.Range).Value2;
                if ((range.Cells[rCnt, 7] as Excel.Range).Value2 != null)
                    productInfo.PKT = (range.Cells[rCnt, 7] as Excel.Range).Value2.ToString();
                productInfo.Cost = (double)(range.Cells[rCnt, 8] as Excel.Range).Value2;
                productInfo.VAT = (double)(range.Cells[rCnt, 9] as Excel.Range).Value2;
                productInfo.CostIncludeVAT = (double)(range.Cells[rCnt, 10] as Excel.Range).Value2;
                productInfo.PriceA = (double)(range.Cells[rCnt, 11] as Excel.Range).Value2;
                productInfo.PriceB = (double)(range.Cells[rCnt, 12] as Excel.Range).Value2;
                productInfo.PriceC = (double)(range.Cells[rCnt, 13] as Excel.Range).Value2;
                productInfo.PriceD = (double)(range.Cells[rCnt, 14] as Excel.Range).Value2;

                //if (rCnt == 2392 || rCnt == 1000 || rCnt == 2000)
                //{

                //}

                ProductInfo existProduct = db.ProductInfos.Local.Where(p => p.BarCode == productInfo.BarCode).SingleOrDefault();

                if (existProduct == null)
                {
                    existProduct = dbProductInfos.Where(p => p.BarCode == productInfo.BarCode).SingleOrDefault();
                        //(from p in dbProductInfos where p.BarCode == productInfo.BarCode select p).SingleOrDefault();
                        //db.ProductInfos.Where(p => p.BarCode == productInfo.BarCode).SingleOrDefault();
                    if (existProduct != null && !string.IsNullOrEmpty(existProduct.BarCode))
                    {
                        existProduct.UpdateValues(productInfo);
                        db.Entry(existProduct).State = EntityState.Modified;
                    }
                    else
                    {
                        db.ProductInfos.Add(productInfo);
                    }
                }
            }
            db.SaveChanges();

            xlWorkBook.Close(false, null, null);
            //xlWorkBook.Close();
            xlApp.Quit();

            FileUtility.ReleaseObject(xlWorkSheet);
            FileUtility.ReleaseObject(xlWorkBook);
            FileUtility.ReleaseObject(xlApp);

        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}